package com.ptswitch.material.pages.base;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.SessionState;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.runtime.ComponentEventException;
import org.apache.tapestry5.services.Request;
import org.hxzon.project.AppRuntimeException;
import org.hxzon.util.ConcurrentUtil;
import org.hxzon.util.EMailUtil;
import org.hxzon.util.EMailUtil.EMail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ptswitch.material.model.common.LoginInfo;
import com.ptswitch.material.model.common.Uzer;
import com.ptswitch.material.pages.user.Login;
import com.ptswitch.material.service.HLogService;
import com.ptswitch.material.service.LoginInfoService;
import com.ptswitch.material.service.UserService;
import com.ptswitch.material.util.AuthenticationException;
import com.ptswitch.material.util.MaterialUtil;
import com.ptswitch.material.util.Messages;
import com.ptswitch.material.util.WebUtil;

public class MaterialBasePage {
    private static final Logger logger = LoggerFactory.getLogger(MaterialBasePage.class);

    @Inject
    private HttpServletRequest servletRequest;
    @Inject
    private HttpServletResponse servletResponse;
    @Inject
    private Request request;
    @Inject
    private HLogService hlogSer;
    @Inject
    private UserService userSer;
    @Inject
    private LoginInfoService loginInfoSer;
    @Inject
    private WebUtil webUtil;
    @Inject
    private MaterialUtil materialUtil;
    @InjectPage
    private Login login;

    @SessionState
    private Messages message;

    private static final LoginInfo GuessLoginInfo = new LoginInfo();
    {
        Uzer guess = new Uzer();
        guess.setUsername(Uzer.Username_Guess);
        GuessLoginInfo.setUser(guess);
    }

    // check
    public void checkUserIsAdmin() {
        if (getVisitor().getAdminGrade() != Uzer.Power_Admin) {
            throw new AuthenticationException("请以管理员身份登录");
        }
    }

    public void checkUserIsAdmins() {
        if (getVisitor().getAdminGrade() != Uzer.Power_Admin && getVisitor().getAdminGrade() != Uzer.Power_Admins) {
            throw new AuthenticationException("请以管理员或超级用户身份登录");
        }
    }

    public void checkUserIsLogin() {
        if ((getVisitor().getUsername().equals("guest"))) {
            throw new AuthenticationException("请先登录");
        }
    }

    public void checkUserIsEqual(Uzer user) {
        if (!getVisitor().getUsername().equals(user.getUsername())) {
            throw new AuthenticationException("请以" + user.getUsername() + "身份登录");
        }
    }

    public void checkUserIsEqual(String username) {
        if (!getVisitor().getUsername().equals(username)) {
            throw new AuthenticationException("请以" + username + "身份登录");
        }
    }

    // check contract
    public void checkUserIsBuyer() {
        if (getVisitor().getDepartment() != Uzer.Department_Buyer) {
            throw new AuthenticationException("只有采购部人员才能操作");
        }
    }

    public void checkUserIsContract() {
        int department = getVisitor().getDepartment();
        if (department != Uzer.Department_ContractAuditor && department != Uzer.Department_Buyer && department != Uzer.Department_Financial && department != Uzer.Department_Production) {
            throw new AuthenticationException("只有采购部，生产部，财务部的人才能操作");
        }
    }

    // If there is no exception event handler, or the exception event handler
    // returns null (or is void), then then the exception will be passed
    // to the RequestExceptionHandler service
    Object onException(Throwable cause) {
        logger.error("root:" + cause.getClass(), cause);
        // ComponentEventException
//        while (cause instanceof ComponentEventException || cause instanceof OldRuntimeException) {
//            cause = cause.getCause();
//            logger.error("cause:" + cause.getClass());
//        }
        while (cause instanceof ComponentEventException) {
            cause = cause.getCause();
        }
        if (cause instanceof AuthenticationException) {
            setMessage(cause.getMessage());
            return login.initialize(getWebUrl() + request.getPath());
        } else if (cause instanceof AppRuntimeException) {
            setMessage(cause.getMessage());
        } else {
        }
        return this;
//		throw new RuntimeException("test");
    }

    // h log
    public void hlog(String overview, Object o) {
        hlogSer.log(getLoginInfo().getUser(), overview, o);
    }

    public void hlog(String overview) {
        hlogSer.log(getLoginInfo().getUser(), overview);
    }

    //send email
    public void sendEMail(final EMail email) {
        ConcurrentUtil.execute(new Runnable() {
            public void run() {
                EMailUtil.sendAndWait(email);
//				if (sendOk) {
//					setMessage("邮件发送成功");
//				} else {
//					setMessage("邮件发送失败");
//				}
            }
        });
    }

    // server info
    private static String webUrl;

    public String getWebUrl() {
        if (webUrl == null) {
            // host : port /web
//			webUrl = "http://" + servletRequest.getLocalAddr() + ":" + servletRequest.getLocalPort() + servletRequest.getContextPath();
            webUrl = "http://" + request.getServerName() + ":" + request.getLocalPort() + request.getContextPath();
            logger.info("web url:" + webUrl);
        }
        return webUrl;
    }

    // get and set
    public String getMessage() {
        return message.read();
    }

    public void setMessage(String message) {
        this.message.write(message);
    }

    public Uzer getVisitor() {
        return getLoginInfo().getUser();
    }

    public LoginInfo getLoginInfo() {
        Cookie cookies[] = servletRequest.getCookies();
        LoginInfo cookie = WebUtil.getLoginInfoCookie(cookies);
        LoginInfo loginInfo = loginInfoSer.findByUsernameAndLoginToken(cookie.getUsername(), cookie.getId());
        if (loginInfo == null) {
            loginInfo = GuessLoginInfo;
            logger.info("login guest");
        } else {
            loginInfo.setUser(userSer.findByUsername(loginInfo.getUsername()));
            logger.info("cookie login:{}", loginInfo.getUser());
        }
        return loginInfo;
    }

    public String getBackUrl() {
//		return servletRequest.getHeader("Referer");
        return request.getHeader("Referer");
    }

    public WebUtil getWebUtil() {
        return webUtil;
    }

    public MaterialUtil getMaterialUtil() {
        return materialUtil;
    }
}
